﻿using System;
using System.Linq.Expressions;
using FT.Architecture.Utils.Reflection;

namespace FT.Architecture.Queries
{
    public class Criterion<T>
    {
        private Criterion(Expression<Func<T, object>> property, object value, CriteriaOperator criteriaOperator)
        {
            PropertyName = Reflection.GetCombinedProperty(property);
            PropertyPath = property;
            Value = value;
            CriteriaOperator = criteriaOperator;
        }

        public string PropertyName 
        {
            get; private set;
        }

        public Expression<Func<T, object>> PropertyPath { get; private set; }

        public object Value { get; private set; }

        public CriteriaOperator CriteriaOperator { get; private set; }

        internal static Criterion<T> Create(Expression<Func<T, object>> expression, object value, CriteriaOperator criteriaOperator)
        {
            var myCriterion = new Criterion<T>(expression, value, criteriaOperator);
            return myCriterion;
        }

        internal static Criterion<T> Create(Expression<Func<T, object>> expression, CriteriaOperator criteriaOperator)
        {
            if (criteriaOperator != CriteriaOperator.IsNull && criteriaOperator != CriteriaOperator.IsNotNull)
            {
                throw new Exception("A criteria without a value can only have an operator of IsNull or IsNotNull");
            }

            var myCriterion = new Criterion<T>(expression, null, criteriaOperator);
            return myCriterion;
        }
    }
}
